import { xphost, v3host } from '@/request/requestAdress';
import { navigateDlbMini } from '@/utils/index';
import Dialog from '@/wxcomponents/vant/dialog/dialog';

// 请求失败
const requestFailedToast = (text) => {
  const msg = text || '服务器又开小差了，请稍后再试';
  wx.showToast({
    title: msg,
    icon: 'none',
    duration: 2000,
  });
};

// 用户登录信息验证失败
const authenticationFailed = () => {
  // clearTimeout(timeTologin);
  // timeTologin = setTimeout(() => {
  //   wx.clearStorageSync();
  // }, 1500);
  Dialog.confirm({
    context: this,
    title: '提示',
    message: '您还未登录，是否立即前往登录？',
    confirmButtonText: '确定',
    confirmButtonColor: '#2361FF',
  })
    .then(() => {
      navigateDlbMini('/pages/login/main');
    })
    .catch(() => {});
};

/**
 * 基础请求封装
 * @param { Object } param0 配置项
 * @param { Boolean } param0.ignoreDefaultErrorToast 跳过默认的请求错误toast
 * @param { Function } callback 回调函数，参数为 请求实例
 * @returns
 */
const request = ({ url = '', payload = {}, header = {}, method = 'GET', ignoreDefaultErrorToast = false }, callback) => {
  return new Promise((resolve, reject) => {
    wx.showNavigationBarLoading();
    header.token = wx.getStorageSync('token') || ''
    const ReqTask = wx.request({
      url: `${url}`,
      data: payload,
      header,
      method,
      responseType: 'text',
      success: (res) => {
        if (res.statusCode === 200) {
          if (res.data.code === 4002) {
            requestFailedToast('此用户已注销，请重新注册登录');
            authenticationFailed();
          } else if (res.data.code === 200) {
            resolve(res.data);
          } else {
            requestFailedToast(res.data.msg || res.msg || '数据请求失败');
          }
        } else {
          if (res.statusCode === 401) {
            requestFailedToast('登录信息已过期，请重新登录');
            wx.setStorageSync('token', '')
            wx.setStorageSync('userInfo', {})
          } else if (res.statusCode === 4002) {
            requestFailedToast('此用户已注销，请重新注册登录');
            authenticationFailed();
          } else if (!ignoreDefaultErrorToast) {
            requestFailedToast(res.data?.message || res.data?.msg || '');
          }
          reject(res);
        }
      },
      fail: (res) => {
        if (res.errMsg !== 'request:fail abort') {
          requestFailedToast();
        }
        reject(res);
      },
      complete: () => {
        wx.hideNavigationBarLoading();
      },
    });
    // 回调函数返回 请求实例
    // eslint-disable-next-line no-unused-expressions
    callback && callback(ReqTask);
  });
};

/**
 * 选品服务接口请求
 * @param {*} config request函数的参数，codeIgnore: 是否需要忽略 res.code 的处理
 * @returns
 */
const xpinRequest = (config = {}, callback = null) => {
  return request(
    {
      ...config,
      url: xphost + config.url,
    },
    callback
  ).then((res) => {
    // 配置 codeIgnore 为true，则不处理接口反馈code，并返回完整响应体
    if (config.codeIgnore) {
      return res;
    }
    // 响应体 code 为 1000 时，表示处理正常，返回 响应体中的 data
    if (res.code === 1000) {
      return res.data;
    }
    requestFailedToast(res.msg);
    throw new Error(`${res.code}: ${res.msg}`);
  });
};

/**
 * 微服务接口
 * @param {*} config request函数的参数，codeIgnore: 是否需要忽略 res.code 的处理
 * @returns
 */
const dlbV3Request = (config = {}, callback = null) => {
  return request(
    {
      ...config,
      url: v3host + config.url,
    },
    callback
  ).then((res) => {
    // 微服务接口，当 http status code 为 200时，表示属于理想结果，直接反馈 响应体 的 data
    if (res.code === 0 && res.http === 200) {
      return res.data;
    }
    // 如果响应体中的 code 、 http 不为正确值，则表示接口返回不符合约定
    throw new Error(`${res.http}: ${res.code}`);
  });
};

export { request, xpinRequest, dlbV3Request };
